package org.codetranslators.compiler.abstractassembly;

import java.util.Stack;

import org.codetranslators.common.Label;
import org.codetranslators.common.Temp;

public class AssemConst extends AssemExp
{
	private int value;
	
	public AssemConst(int v) 
	{
		value = v;
	}
	
	public AssemExpList children() 
	{
		return null;
	}
	
	public int getValue()
	{
		return value;
	}
	
	public int getType()
	{
		return AssemType.INT_TYPE;
	}
	
	public AssemType translateToCJump(Label testLabel, Label endLabel)
	{
		// Move this value to a temporary
		Temp temp = new Temp();
		AssemTemp assemTemp = new AssemTemp(temp);
		AssemMove assemMov = new AssemMove(assemTemp, this);
		
		// Create a constant 0
		AssemConst assemConst0 = (AssemConst) new AssemConst(0);
		
		// Create a conditional based on whether the above temporary is 1 or 0
		AssemCJump tempCJump = new AssemCJump(AssemCJump.GT, assemTemp, assemConst0,
				testLabel, endLabel); 
		
		Stack seqStack = new Stack();
		seqStack.push(assemMov);
		seqStack.push(tempCJump);
		
		return translateSeqStatement(seqStack);
	}
	
	public AssemType translateToIntType()
	{
		// Create a new temporary to hold this constant
		Temp temp = new Temp();
		AssemTemp assemTemp = new AssemTemp(temp);
		
		// Move this value into the temporary and return the seq-exp
		AssemMove assemMove = new AssemMove(assemTemp, this);
		
		return new AssemSeqExp(assemMove, assemTemp);
	}
	
	public String getDescription()
	{
		return "CONST(" + value + ")";
	}
	
	public AssemSeq translateSeqStatement(Stack seq)
	{
		AssemSeq retAssemType = null;
		
		while(!seq.isEmpty())
		{
			AssemType temp = (AssemType)seq.pop();
			// If there is an expression in this sequence, coerce it to a statement,
			// since we are building a list of statements 
			if(temp instanceof AssemExp)
			{
				AssemExp exp = (AssemExp) temp;
				temp = exp.translateToStatement();
			}
			retAssemType  = new AssemSeq((AssemStm)temp, (AssemStm)retAssemType);
		}
		
		return retAssemType;
	}
	
	public AssemExp build(AssemExpList list)
	{
		return this;
	}
	
	public AssemSeqExp canonize()
	{
		return new AssemSeqExp(null, this);	
	}
	
	public int getExpType()
	{
		return AssemExp.CONST;
	}
}
